/**************************************************************************
Writen by: Cedric Snoy
Started: 4/20/12
Location: The Master version is located on the zero-defect-go-parser git
    repository in the scr directory.
Reason: This program as a whole is being written for Zero Defect Software
    Designed to fulfill the requirements of the final project. This program is
    a review tool for Go games, stored in the sgf format, that is of the 9 by
    9 size. This file specifically is the top level logic and the interpreter
    of user input.
Context: Several other source files are included in this project, including
    reader and board files. All of which are locked in the same directory as
    this file. As stated this is the high end logic and the interpreter of
    of user input.
**************************************************************************/
#include <stdio.h> //included for in/out put operations
#include <stdlib.h> 
#include <ctype.h> 
#include <string.h>//included for string comparison
#include "reader.h"//included for file handeling fuctions
char *NEXT="n\0";//string to be entered by user to move to the next position
char *PREV="b\0";//string to be entered by user to move the the previous 
                 //position

/**
 *[stdout:=stdout + sequence of positions and input error messages
 *     specifed by user input]
 */
void interact(Position *pos)
{
    char *input;
    while(true)//loop until killed by os or other
    {
    /*body
     *[let input be a line of input form stdin in eather case
     * if input==NEXT->
     *     if pos->next!=pos
     *         stdout:=stdout + pos->next->board
     *         pos:=pos->next
     *     else->
     *         stdout:=stdout + statement that there is no next move
     * elseif input==PREV
     *     if pos->prev!=pos->
     *         stdout:=stdout+pos->board
     *         pos:=pos->prev
     *     else->
     *         stdout:=stdout + statement that there is not a previous move
     * else->
     *     stdout:=stdout + a message describing the user error and
     *         valid commands]
     */
        /*-1
         *[input:=a line of input from stdin]
         */
        input=gets();
        /*-2
         *[if input==NEXT->
         *     if pos->next!=pos
         *         stdout:=stdout + pos->next->board
         *         pos:=pos->next
         *     else->
         *         stdout:=stdout + statement that there is no next move
         * elseif input==PREV
         *     if pos->prev!=pos->
         *         stdout:=stdout+pos->board
         *         pos:=pos->prev
         *     else->
         *         stdout:=stdout + statement that there is not a previous move
         * else->
         *     stdout:=stdout + a message describing the user error and
         *         valid commands]
         */
        if(strcmp(input, NEXT)==0)
        {
            /* -2.1
             *[if pos->prev!=pos->
             *     stdout:=stdout + pos->next->board
             *     pos:=pos->next
             * else->
             *     stdout:=stdout + statement that there is no next move]
             */
            pos=nextPosition(pos);
        }
        else if(strcmp(input, PREV)==0)
        {
            /*-2.2
             *[if pos->prev!=pos->
             *     stdout:=stdout+pos->board
             *     pos:=pos->prev
             * else->
             *     stdout:=stdout + statement that ther is no previous move]
             */
            pos=prevPosition(pos);
        }
        else
        {
            /* -2.3
             *[stdout:=stdout + a message describing the user error and
             *     available user input]
             */
            printf("That is not a recognized command. correct commands\n"
                "Are \"n\" to go the the next position and\"b\" to go \n"
                "to go back a position\n");
        }
        /*-3
         *[*input:=deallocated]
         */
        free(input);
    }
}
/**
*[let A, B, and C all be allocated pointer to their corresponding structs->
* A, B, C := deallocated
* A->string, B->moves:= deallocated
* C->moves:=I]
*/
void clean(fileStruct *A, parseStruct *B, gameStruct *C)
{
    /*-1
     *[A->string:=deallocated
     * A:=deallocated]
     */
    free(A->string);
    free(A);
    /*-2
     *[B->moves:=deallocated
     * B:=deallocated]
     */
    for(int i=0; i<dead.size; i++)
    {
        /*-2 Body 
         *[*B->moves[i]:=deallocated]
         */
        free(B->moves[i]);
    }
    free(B->moves);
    free(B);
    /*-1
     *[C:=deallocated]
     */
    free(C);
}
 /**
 *[if only one argument was given->
 *     if file named by argv[1] can be opened and read and is valid->
 *         stdout:=stdout + sequence of positions and input error
 *             messages specified by user input
 *     else->
 *         stdout:=stdout + message describing why the file was not read
 * else->
 *     stdout:=stdout + message describing correct calling of the program]
 */
void main(int argc, char* argv[])
 {  
    fileStruct *ret1;
    parseStruct *ret2;
    gameStruct *ret3;
    Position *stack;
    /*-1
     *[if the argument count was not one->
     *     stdout:=stdout + message describing correct calling of the
     *         program
     *     return
     * else->
     *     if file named by argv[1] can be opened, read and is valid->
     *         stdout:=stdout + sequence of positions specified by the user
     *             input + input error messages
     *         stack:=a list of board positions and related messages
     *     else->
     *         stdout:=stdout + message describing why the file was not
     *             read or valid
     *         return]
     */
    if(argc!=2)
    {
        /*-1.1
         *[stdout:=stdout + message describing correct calling of the
         *         program
         * return]
         */
        printf("incorrect number of arguments expected: GoReviewer "
            "[one sfg file]\n");
        return;
    }
    else
    {
        /*-1.2.1
         *[if file named by argv[1] can not be opened and read->
         *     ret1->status:=ERROR
         * else->
         *     ret1->status:=SUCCESS
         *     ret1->string:=a char array contaning the content of the file]
         */
        ret1=readFile(argv[1]);
        /*-1.2.2
         *[if ret1->status==ERROR->
         *     stdout:=stdout + message describing why the file was not
         *         read
         *     return
         * else->I]
         */
        if(ret1->status==ERROR)
        {
            printf("%s either could not be opened or read\n", argv[1]);
            return;  
        }
        /*-1.2.3
         *[if ret1->string could not be parsed->
         *     ret2->status:=ERROR
         * else->
         *     ret2->status:=SUCCESS
         *     ret2->moves:= a list of char arrays each contaning a move
         *     ret2->size:=number of moves]
         */
        ret2=parseString(ret1->string);
        /*-1.2.4
         *[if ret2->status==ERROR->
         *     stdout:=stdout + message discribing why the file was not
         *         read
         *     return
         * else->I]
         */
        if(ret2->returnValue==ERROR)
        {
           printf("%s could not be parsed. It is likely not compatible "
               "with this program. Boards must be 9x9\n",argv[1]);
           return;
        }
        /*-1.2.5
         *[if ret2->moves can't be converted to a list of positions->
         *     ret3->status:=ERROR
         * else->
         *     ret3->status:=SUCCESS
         *     ret3->moves:= the position at the start of a list that is
         *         representing a game]
         */
        ret3=makeGame(ret2->moves, ret2->size);
        /*-1.2.6
         *[if ret3->status==ERROR->
         *     stdout:=stdout + message describing that the game was not
         *         made
         *     return
         * else->I]
         */
        if(ret3->status==ERROR)
        {
            printf("The moves in %s are malformed and thus could not be\n"
                "made into a game\n", argv[1]);
            return;
        }
        /*-1.2.7*/
        stack=ret3->moves;
        /*-1.2.8
         *[ret1, ret2, ret3 := deallocated
         * ret1->string, ret2->moves:= deallocated
         * ret3->moves:=I]
         */
        clean(ret1,ret2,ret3);
        /*-1.2.9
         *[stdout:=stdout + sequence of positions and input error messages
         *     indicated by the user]
         */
        interact(stack);
    }
}    
